/*
 * StatisticWriter.java
 *
 * Created on 28 de Abril de 2006, 17:04
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package hubsniffer.db;

import libjdc.dc.client.messages.ExceptionMessage;
import hubsniffer.DCHub;
import libjdc.dc.client.messages.RawMessage;
import libjdc.dc.client.User;
import libjdc.dc.client.UserList;
import hubsniffer.db.util.Util;
import libjdc.dc.log.Log;
import java.io.UnsupportedEncodingException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;

/**
 *
 * @author Daniel Botelho
 */
public class StatisticWriter {
    
    private int statistic_id;
    private DataBaseManager db; 
    private Date start;
    
    private void write_sql(String sql,boolean iso) throws UnsupportedEncodingException, SQLException{  
        db.writeRawSql(sql,iso);
    }
    
    /**
     *  Cria um Objecto do tipo StatisticWriter.
     *  � necess�rio chamar um m�todo public commit, para adicionar esta estatistica a BD 
     */
    public StatisticWriter(Date start, DataBaseManager db) {
        this.db = db;
        this.statistic_id = 0;
        this.start = start;
    }   
    
    public void update(DCHub hub,int statistic_id) throws SQLException, UnsupportedEncodingException{
    	String message = "UPDATE hub SET statistic_id="+statistic_id+", hub_name='"+Util.escapeString(hub.getHubName())+"', hub_topic='"+Util.escapeString(hub.getHubInfo().getTopic())+"' WHERE hub_id="+hub.getHub_id();
        write_sql(message,true);
    }
    
    
    private void addExceptionMessages(int statistic_id,LinkedList<ExceptionMessage> exceptionMessages) throws SQLException, UnsupportedEncodingException{
        Iterator<ExceptionMessage> it = exceptionMessages.iterator();
        
        while(it.hasNext()){
            ExceptionMessage next = it.next();
            String message = "INSERT INTO \"exception_msg\" (\"exception_msg_date\", \"exception_msg_trace\", \"statistic_id\") VALUES (" +
                    "'"+next.getData()+"', '"+Util.escapeString(next.getTrace())+"', '"+statistic_id+"')";
            write_sql(message,true);
        }
    }
    
    private void addRawMessages(int statistic_id,LinkedList<RawMessage> rawMessages) throws SQLException, UnsupportedEncodingException{
        Iterator<RawMessage> it = rawMessages.iterator();
        
        while(it.hasNext()){
            RawMessage next = it.next();
            String message = "INSERT INTO \"raw_msg\" (\"raw_msg_date\", \"raw_msg_from\", \"raw_msg_to\", \"raw_msg_message\", \"statistic_id\") VALUES (" +
                    "'"+next.getDate()+"', '"+next.getFrom()+"', '"+next.getTo()+"', '"+Util.escapeString(next.getMessage())+"', '"+statistic_id+"')";
            write_sql(message,true);
        }
    }
    
    private void addUserList(int statistic_id,UserList userList) throws SQLException, UnsupportedEncodingException{
        Iterator<User> it = userList.iterator();
        
        while(it.hasNext()){
            User next = it.next();
            String message = "INSERT INTO \"dc_user\" (\"dc_user_nick\", \"dc_user_description\", \"dc_user_speed\", \"dc_user_email\", \"dc_user_share\", \"statistic_id\", \"dc_user_ip\",\"dc_user_op\") VALUES (" +
                    "'"+Util.escapeString(next.getUserInfo().getNick())+"', '"+Util.escapeString(next.getUserInfo().getDescription())+"', '"+next.getUserInfo().getSpeed()+"', '"+Util.escapeString(next.getUserInfo().getEmail())+"', '"+next.getUserInfo().getSharedBytes()+"', '"+statistic_id+"', '"+next.getHost()+"', '"+next.getUserInfo().isOp()+"')";
            write_sql(message,true);
        }
    }
    
     /**
     *  Retorna um ID disponivel na bd
     */
    private int getAvailableStatisticId() throws SQLException{
        ResultSet rs = db.getSql_stm().executeQuery("SELECT MAX(statistic_id) FROM statistic");
        
        rs.next();     
        
        return rs.getInt(1);
    }
    
    
    public void addStatistic(Date date,DCHub hub) throws SQLException, UnsupportedEncodingException{
        int statistic_id = 0; 
        //Date date = hub.getHubLog().getStart();
        String MTOD ="";
        int user_count = hub.getHubSession().getUserList().size();
        String statistic_share = hub.getHubSession().getUserList().getUserShare()+"";
        int hub_id = hub.getHub_id();
        String hub_status = hub.getHubSession().getHubStatus().toString();
        int software_id = (hub.getHubSession().getHubClient()== null) ? 0: hub.getHubSession().getHubClient().getSoftware_id();
        String is_online = (hub.getHubSession().isIs_online()? "TRUE":"FALSE");
                
        String message = "INSERT INTO \"statistic\" (\"date\", \"is_online\", \"info\", \"user_count\", \"hub_id\", \"software_id\", \"statistic_share\", \"hub_status\") VALUES (" +
                "'"+date+"', "+is_online+", '"+MTOD+"', '"+user_count+"', '"+hub_id+"', '"+software_id+"', '"+ statistic_share + "', '"+hub_status+"')";
        write_sql(message,true);
        
        statistic_id = getAvailableStatisticId();
        
        /*
         * Depois insere os DC_Users
         */
        addUserList(statistic_id,hub.getHubSession().getUserList());
        
        /*
         * Depois insere os RawMessages
         */
        addRawMessages(statistic_id,hub.getHubSession().getRaw_messages());
        
        /*
         * Depois insere os ExceptionMessage
         */
        addExceptionMessages(statistic_id,hub.getHubSession().getException_messages());
        
        /*
         * Actualiza o hub
         */
        update(hub,statistic_id);

    }
    
    public void commit( Iterator<DCHub> it) {
        
        
        try {
            db.emptyTable("raw_msg");
            db.emptyTable("exception_msg");
            db.emptyTable("dc_user");
        } catch (SQLException ex) {
            ex.printStackTrace(Log.err);
        }
        
        while(it.hasNext()){
            try {
                addStatistic(this.start,it.next());
            } catch (SQLException ex) {
                ex.printStackTrace(Log.err);
            }catch (UnsupportedEncodingException ex) {
                ex.printStackTrace(Log.err);
            }
        }
        
        
    }
    
    public void commit( Iterator<DCHub> it,Iterator<DCHub> it2) {
        
        
        try {
            db.emptyTable("raw_msg");
            db.emptyTable("exception_msg");
            db.emptyTable("dc_user");
        } catch (SQLException ex) {
            ex.printStackTrace(Log.err);
        }
        
        while(it.hasNext()){
            try {
                addStatistic(this.start,it.next());
            } catch (SQLException ex) {
                ex.printStackTrace(Log.err);
            }catch (UnsupportedEncodingException ex) {
                ex.printStackTrace(Log.err);
            }
        }
        
        while(it2.hasNext()){
            try {
                addStatistic(this.start,it2.next());
            } catch (SQLException ex) {
                ex.printStackTrace(Log.err);
            }catch (UnsupportedEncodingException ex) {
                ex.printStackTrace(Log.err);
            }

        }
        
    }

}
